package jp.co.katagaki.crossword.io.writer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

import jp.co.katagaki.crossword.puzzle.Word;
import jp.co.katagaki.util.ArrayUtil;
import jp.co.katagaki.util.Assertions;

import org.apache.commons.lang.StringUtils;

import au.com.bytecode.opencsv.CSVParser;
import au.com.bytecode.opencsv.CSVWriter;

/**
 * {@link PuzzleWordWriter}の{@link CSVWriter}実装クラス。
 *
 * @author naotake
 */
public class PuzzleWordCsvWriter implements PuzzleWordWriter {

    private String fileName;
    private CSVWriter writer;

    /**
     * 指定されたファイル名を基にインスタンスを生成する。
     *
     * @param fileName
     *            ファイル名
     */
    public PuzzleWordCsvWriter(String fileName) {
        this.fileName = fileName;
        initialize();
    }

    private void initialize() {
        String pathName = "/"
                + StringUtils.replace(PuzzleWordCsvWriter.class.getPackage()
                        .getName(), ".", "/") + "/" + fileName;
        URL url = PuzzleWordCsvWriter.class.getResource(pathName);
        try {
            writer = new CSVWriter(new PrintWriter(new File(url.toURI())),
                    CSVParser.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
        } catch (FileNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        } catch (URISyntaxException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    @Override
    public void write(Word word) {
        Assertions.assertNotNull("単語", word);

        writer.writeNext(convertToArray(word));
        try {
            writer.flush();
        } catch (IOException e) {
            // NOP
        }
    }

    @Override
    public void writeAll(List<Word> wordList) {
        Assertions.assertNotNull("単語一覧", wordList);

        for (Word word : wordList) {
            write(word);
        }
    }

    private String[] convertToArray(Word word) {
        return ArrayUtil.asArray(word.getWord(), word.getGenre().toString(),
                word.getHint());
    }
}
